/**
  **************************************************************************
  * @file     mpu6050.h
  * @brief    header file of mpu6050.
  **************************************************************************
  *                       Copyright notice & Disclaimer
  *
  * The software Board Support Package (BSP) that is made available to
  * download from Artery official website is the copyrighted work of Artery.
  * Artery authorizes customers to use, copy, and distribute the BSP
  * software and its related documentation for the purpose of design and
  * development in conjunction with Artery microcontrollers. Use of the
  * software is governed by this copyright notice and the following disclaimer.
  *
  * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
  * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
  * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
  * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
  * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
  * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
  *
  **************************************************************************
  */

/* define to prevent recursive inclusion -------------------------------------*/
#ifndef __MPU6050_H
#define __MPU6050_H

#ifdef __cplusplus
extern "C" {
#endif

/* includes ------------------------------------------------------------------*/
#include "i2c_application.h"
#include "at32f403a_407_board.h"

/* register macro ------------------------------------------------------------*/
#define MPU_REG_SELF_TESTX               0x0D
#define MPU_REG_SELF_TESTY               0x0E
#define MPU_REG_SELF_TESTZ               0x0F
#define MPU_REG_SELF_TESTA               0x10
#define MPU_REG_SAMPLE_RATE              0x19
#define MPU_REG_CFG                      0x1A
#define MPU_REG_GYRO_CFG                 0x1B
#define MPU_REG_ACCEL_CFG                0x1C
#define MPU_REG_MOTION_DET               0x1F
#define MPU_REG_FIFO_EN                  0x23
#define MPU_REG_I2CMST_CTRL              0x24
#define MPU_REG_I2CSLV0_ADDR             0x25
#define MPU_REG_I2CSLV0                  0x26
#define MPU_REG_I2CSLV0_CTRL             0x27
#define MPU_REG_I2CSLV1_ADDR             0x28
#define MPU_REG_I2CSLV1                  0x29
#define MPU_REG_I2CSLV1_CTRL             0x2A
#define MPU_REG_I2CSLV2_ADDR             0x2B
#define MPU_REG_I2CSLV2                  0x2C
#define MPU_REG_I2CSLV2_CTRL             0x2D
#define MPU_REG_I2CSLV3_ADDR             0x2E
#define MPU_REG_I2CSLV3                  0x2F
#define MPU_REG_I2CSLV3_CTRL             0x30
#define MPU_REG_I2CSLV4_ADDR             0x31
#define MPU_REG_I2CSLV4                  0x32
#define MPU_REG_I2CSLV4_DO               0x33
#define MPU_REG_I2CSLV4_CTRL             0x34
#define MPU_REG_I2CSLV4_DI               0x35
#define MPU_REG_I2CMST_STA               0x36
#define MPU_REG_INTBP_CFG                0x37
#define MPU_REG_INT_EN                   0x38
#define MPU_REG_INT_STA                  0x3A
#define MPU_REG_ACCEL_XOUTH              0x3B
#define MPU_REG_ACCEL_XOUTL              0x3C
#define MPU_REG_ACCEL_YOUTH              0x3D
#define MPU_REG_ACCEL_YOUTL              0x3E
#define MPU_REG_ACCEL_ZOUTH              0x3F
#define MPU_REG_ACCEL_ZOUTL              0x40
#define MPU_REG_TEMP_OUTH                0x41
#define MPU_REG_TEMP_OUTL                0x42
#define MPU_REG_GYRO_XOUTH               0x43
#define MPU_REG_GYRO_XOUTL               0x44
#define MPU_REG_GYRO_YOUTH               0x45
#define MPU_REG_GYRO_YOUTL               0x46
#define MPU_REG_GYRO_ZOUTH               0x47
#define MPU_REG_GYRO_ZOUTL               0x48
#define MPU_REG_I2CSLV0_DO               0x63
#define MPU_REG_I2CSLV1_DO               0x64
#define MPU_REG_I2CSLV2_DO               0x65
#define MPU_REG_I2CSLV3_DO               0x66
#define MPU_REG_I2CMST_DELAY             0x67
#define MPU_REG_SIGPATH_RST              0x68
#define MPU_REG_MDETECT_CTRL             0x69
#define MPU_REG_USER_CTRL                0x6A
#define MPU_REG_PWR_MGMT1                0x6B
#define MPU_REG_PWR_MGMT2                0x6C
#define MPU_REG_FIFO_CNTH                0x72
#define MPU_REG_FIFO_CNTL                0x73
#define MPU_REG_FIFO_RW                  0x74
#define MPU_REG_DEVICE_ID                0x75

/* exported macro ------------------------------------------------------------*/
#define I2C_TIMEOUT                      0x0002FFFF  /* 50 ms time out */

#define MPU_I2C_SPEED                    400000   /* 400K */

#define MPU_AD0_PIN_LOW
//#define MPU_AD0_PIN_HIGH

#define MPU_CAL_CNT                      100

#define MPU_I2C_PORT                     I2C1
#define MPU_I2C_CLK                      CRM_I2C1_PERIPH_CLOCK
#define MPU_I2C_DMA                      DMA1
#define MPU_I2C_DMA_CLK                  CRM_DMA1_PERIPH_CLOCK

#define MPU_SCL_GPIO_CLK                 CRM_GPIOB_PERIPH_CLOCK
#define MPU_SCL_GPIO_PIN                 GPIO_PINS_6
#define MPU_SCL_GPIO_PORT                GPIOB

#define MPU_SDA_GPIO_CLK                 CRM_GPIOB_PERIPH_CLOCK
#define MPU_SDA_GPIO_PIN                 GPIO_PINS_7
#define MPU_SDA_GPIO_PORT                GPIOB

#define MPU_AD0_GPIO_CLK                 CRM_GPIOB_PERIPH_CLOCK
#define MPU_AD0_GPIO_PIN                 GPIO_PINS_8
#define MPU_AD0_GPIO_PORT                GPIOB

#define MPU_INT_GPIO_CLK                 CRM_GPIOB_PERIPH_CLOCK
#define MPU_INT_GPIO_PIN                 GPIO_PINS_9
#define MPU_INT_GPIO_PORT                GPIOB
#define MPU_INT_PORT_SOURCE              GPIO_PORT_SOURCE_GPIOB

#define MPU_INT_SCFG_PinsSource          GPIO_PINS_SOURCE9
#define MPU_INT_EXINT_LINE               EXINT_LINE_9
#define MPU_INT_EXINT_LINE_IRQ           EXINT9_5_IRQn
#define MPU_INT_EXINT_IRQHandler         EXINT9_5_IRQHandler

#define MPU_I2C_DMA_TX_Channel           DMA1_CHANNEL6
#define MPU_I2C_DMA_TX_IRQn              DMA1_Channel6_IRQn
#define MPU_I2C_DMA_TX_IRQHandler        DMA1_Channel6_IRQHandler

#define MPU_I2C_DMA_RX_Channel           DMA1_CHANNEL7
#define MPU_I2C_DMA_RX_IRQn              DMA1_Channel7_IRQn
#define MPU_I2C_DMA_RX_IRQHandler        DMA1_Channel7_IRQHandler

#define MPU_I2C_EVT_IRQn                 I2C1_EVT_IRQn
#define MPU_I2C_ERR_IRQn                 I2C1_ERR_IRQn
#define MPU_I2C_EVT_IRQHandler           I2C1_EVT_IRQHandler
#define MPU_I2C_ERR_IRQHandler           I2C1_ERR_IRQHandler

#define MPU_AD0_HIGH()                   gpio_bits_set(MPU_AD0_GPIO_PORT, MPU_AD0_GPIO_PIN)
#define MPU_AD0_LOW()                    gpio_bits_reset(MPU_AD0_GPIO_PORT, MPU_AD0_GPIO_PIN)

#ifdef MPU_AD0_PIN_LOW
  #define MPU_ADDRESS                    0xD0 /*!< AD0 low:  adress 0b1101000 0xD0 */
#else
  #define MPU_ADDRESS                    0xD2 /*!< AD0 high: adress 0b1101001 0xD2*/
#endif


/** @defgroup I2C_library_handler
  * @{
  */

typedef struct
{
  __IO int16_t                           ax;      /*!< accelerometer x */
  __IO int16_t                           ay;      /*!< accelerometer y */
  __IO int16_t                           az;      /*!< accelerometer z */
  __IO int16_t                           gx;      /*!< gyroscope x */
  __IO int16_t                           gy;      /*!< gyroscope y */
  __IO int16_t                           gz;      /*!< gyroscope z */
  __IO float                             temp;    /*!< temperature  */
  __IO int16_t                           ax_cal;  /*!< accelerometer x calibration value */
  __IO int16_t                           ay_cal;  /*!< accelerometer y calibration value */
  __IO int16_t                           az_cal;  /*!< accelerometer z calibration value */
  __IO int16_t                           gx_cal;  /*!< gyroscope x calibration value */
  __IO int16_t                           gy_cal;  /*!< gyroscope y calibration value */
  __IO int16_t                           gz_cal;  /*!< gyroscope z calibration value */
  __IO float                             angle_x; /*!< euler angle roll */
  __IO float                             angle_y; /*!< euler angle pitch */
  __IO float                             angle_z; /*!< euler angle yaw */
  __IO float                             q0;      /*!< euler angle roll */
  __IO float                             q1;      /*!< euler angle pitch */
  __IO float                             q2;      /*!< euler angle yaw */
  __IO float                             q3;      /*!< euler angle yaw */

} mpu_handle_type;

extern mpu_handle_type mpu;
extern i2c_handle_type hi2cx;
extern volatile uint8_t mpu_data_read_flag;

/**
  * @}
  */

/* exported functions ------------------------------------------------------- */
i2c_status_type mpu6050_write_buf(uint8_t reg, uint8_t len, uint8_t *buf);
i2c_status_type mpu6050_read_buf(uint8_t reg, uint8_t len, uint8_t *buf);

error_status mpu6050_init(void);
error_status mpu6050_data_get(mpu_handle_type *mpu);
error_status mpu6050_calibrate(mpu_handle_type *mpu);


#ifdef __cplusplus
}
#endif

#endif

